#include "widget.h"
#include "ui_widget.h"
#include<QSerialPortInfo>
#include<QMessageBox>
#include<Qmap>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 定义一个字符串列表，用于存储所有可用的串口名称
    QStringList serialNamePort;
    // 创建QSerialPort对象实例，指定父对象为当前窗口(this)，用于自动内存管理
    serialPort = new QSerialPort(this);
    // 遍历系统中所有可用的串口设备
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()){
    // 将每个串口的端口名称(如"COM3"或"/dev/ttyUSB0")添加到列表中
        serialNamePort<<info.portName();
    }
    // 连接串口的"数据就绪"信号到槽函数：当串口有数据到达时触发serialReadyRead_slot()
    connect(serialPort,SIGNAL(readyRead()),this,SLOT(serialReadyRead_slot()));
    // 将可用串口名称列表添加到UI的下拉选择框(serialCb)中
    ui->serialCb->addItems(serialNamePort);
    // 绑定"HEX显示"复选框
    connect(ui->hexDisplayCheckBox, &QCheckBox::stateChanged, [this](int state) {
        hexDisplayEnabled = (state == Qt::Checked); // 勾选时启用HEX显示
    });

    // 绑定"HEX发送"复选框
    connect(ui->hexSendCheckBox, &QCheckBox::stateChanged, [this](int state) {
        hexSendEnabled = (state == Qt::Checked); // 勾选时启用HEX发送
    });
}

Widget::~Widget()
{
    delete ui;
}
void Widget::serialReadyRead_slot() {
    QByteArray data = serialPort->readAll(); // 读取原始字节数据
    QString buf;

    if (hexDisplayEnabled) {
        // 转为十六进制字符串，每个字节用空格分隔（如 "A1 B2"）
        buf = data.toHex(' ').toUpper();
    } else {
        // 直接转为ASCII字符串（如 "Hello"）
        buf = QString(data);
    }

    ui->recvEdit->appendPlainText(buf); // 显示到接收区
}


void Widget::on_openBt_clicked(){
    // 在 Widget 类中添加成员变量
    QSerialPort::BaudRate baudRate;
        const QMap<QString, QSerialPort::BaudRate> baudRateMap = {
          {"1200", QSerialPort::Baud1200},
          {"2400", QSerialPort::Baud2400},
          {"4800", QSerialPort::Baud4800},
          {"9600", QSerialPort::Baud9600},
          {"19200", QSerialPort::Baud19200},
          {"38400", QSerialPort::Baud38400},
          {"115200", QSerialPort::Baud115200}
        };



    // 2. 设置数据位（Data Bits）
    QSerialPort::DataBits dataBits;
        const QMap <QString,QSerialPort::DataBits>dataBitsMap = {
            {"5",QSerialPort::Data5},
            {"6",QSerialPort::Data6},
            {"7",QSerialPort::Data7},
            {"8",QSerialPort::Data8},
        };

    // 3. 设置停止位（Stop Bits）
    QSerialPort::StopBits stopBits;
        const QMap<QString, QSerialPort::StopBits> stopBitsMap = {
            {"1", QSerialPort::OneStop},
            {"1.5", QSerialPort::OneAndHalfStop},
            {"2", QSerialPort::TwoStop}
        };


    // 4. 设置校验位（Parity）
    QSerialPort::Parity parity;
        const QMap<QString, QSerialPort::Parity> parityMap = {
            {"none", QSerialPort::NoParity},
            {"even", QSerialPort::EvenParity},
            {"odd", QSerialPort::OddParity}
        };

    if (serialPort) {
    serialPort->setPortName(ui->serialCb->currentText());
    serialPort->setBaudRate(baudRateMap.value(ui->baudrateCb->currentText(), QSerialPort::Baud9600));
    serialPort->setDataBits(dataBitsMap.value(ui->dataBitsCb->currentText(), QSerialPort::Data8));
    serialPort->setStopBits(stopBitsMap.value(ui->stopBitsCb->currentText(), QSerialPort::OneStop));
    serialPort->setParity(parityMap.value(ui->parityCb->currentText(), QSerialPort::NoParity));
    }
    if(serialPort->open(QIODevice::ReadWrite)){// 尝试以读写模式打开串口
        QMessageBox::information(this,"提示","成功");
        ui->openBt->setEnabled(false);

    }else{
         QMessageBox::critical(this,"错误", QString("打开失败: %1").arg(serialPort->errorString()));
    }
}
void Widget::on_closeBt_clicked()
{
    serialPort->close();
    ui->openBt->setEnabled(true);
}


void Widget::on_sendBt_clicked() {
    QString text = ui->sendEdit->text(); // 获取用户输入的文本

    QByteArray sendData;
    if (hexSendEnabled) {
        // HEX模式：移除空格后转为二进制数据
        text = text.replace(" ", ""); // 清理输入（允许用户输入"A1 B2"或"A1B2"）
        sendData = QByteArray::fromHex(text.toLocal8Bit()); // 关键转换
    } else {
        // ASCII模式：直接发送文本的字节形式
        sendData = text.toLocal8Bit();
    }

    if (!sendData.isEmpty()) {
        serialPort->write(sendData); // 发送数据
    }
}

void Widget::on_clearBt_clicked()
{
    ui->recvEdit->clear();
}



